package com.regan.erp.util;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Dict;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.*;

/**
 * Function 工具类，对lambda调用
 * @author  zhangby
 * @date  2017/8/5 17:31
 */
public class FunctionUtils {

    /**
     * 接收T对象并返回boolean
     * @param t
     * @param predicate
     * @param <T>
     * @return
     */
    public static <T> boolean predicate(T t,Predicate<T> predicate){
         return predicate.test(t);
    }

    /**
     * 接收T对象，返回E对象
     * @param t
     * @param func
     * @param <T>
     * @param <E>
     * @return
     */
    public static  <T,E> E function(T t,Function<T,E> func){
        return func.apply(t);
    }

    /**
     * 接收T对象，不返回值
     * @param t
     * @param consumer
     * @param <T>
     */
    public static <T> void consumer(T t ,Consumer<T> consumer) {
        consumer.accept(t);
    }

    /**
     * 提供T对象（例如工厂），不接收值
     * @param supplier
     * @param <T>
     * @return
     */
    public static <T> T supplier(Supplier<T> supplier) {
        return supplier.get();
    }

    /**
     * 接收T对象，返回T对象
     * @param t
     * @param supplier
     * @param <T>
     * @return
     */
    public static <T> T unaryOperator(T t,UnaryOperator<T> supplier) {
        return supplier.apply(t);
    }

    /**
     * 接收两个T对象，返回T对象
     * @param t1
     * @param t2
     * @param supplier
     * @param <T>
     * @return
     */
    public static <T> T binaryOperator(T t1,T t2,BinaryOperator<T> supplier) {
        return supplier.apply(t1,t2);
    }

    /**
     * 接收T对象和U对象，返回R对象
     * @param t
     * @param u
     * @param supplier
     * @param <T>
     * @param <U>
     * @param <R>
     * @return
     */
    public static <T,U,R> R biFunction(T t,U u,BiFunction<T,U,R> supplier) {
        return supplier.apply(t,u);
    }

    /**
     * list数据转换
     * @param list list对象
     * @param func lamdba 表达式 function
     * @param <E> 原对象
     * @param <T> 转换完的对象
     * @return
     */
    public static <E,T> List<E> convers(List<T> list, Function<T, E> func) {
        return list.stream().collect(ArrayList::new, (li, p) -> li.add(function(p, func)), List::addAll);
    }

    /**
     * 数据转换
     * @param list
     * @param consumer
     */
    public static <T> void execute(List<T> list, Consumer<T> consumer) {
        list.stream().forEach(consumer::accept);
    }

    /**
     * function Map转换Dict
     * @author zhangby
     * @date 2018/3/16 上午9:56
     */
    public static Function<Map, Dict> mapToDict = d->{
        Dict dt = Dict.create();
        dt.putAll(d);
        return dt;
    };

    /**
     * JsonArray list -> Dict list
     * @param list
     * @return
     * 
     * @author zhangby
     * @date 2018/4/26 上午11:40
     */
    public static List<Dict> jsonArray2DictList(Object list) {
    	Function<Object, Dict> func = d -> JSON.parseObject(JSON.toJSONString(d), Dict.class);
    	List<Object> li = Convert.convert(List.class, list);
		return FunctionUtils.convers(li,func);
    }
}
